/*
 * @Author: 吴世扬 18368095041@163.com
 * @Date: 2025-06-04 11:43:01
 * @LastEditors: 吴世扬 18368095041@163.com
 * @LastEditTime: 2025-06-04 16:46:55
 * @FilePath: /vue3-uniapp/src/service/useEnum/utils.ts
 */
import {
    Subject,
    debounceTime,
    switchMap,
    from,
    shareReplay,
    map,
    type Observable
} from 'rxjs';
import type { EnumItem } from './type';

export const labelValueFormat = <T extends object>(
    target: T[],
    label: keyof T,
    value: keyof T
) => {
    return target.map((item) => {
        const returnVal: EnumItem<T> = {
            label: item[label] as string,
            value: item[value] as string | number,
            origin: item,
            children: []
        };
        if (Reflect.has(item, 'children')) {
            const children = Reflect.get(item, 'children');
            if (Array.isArray(children)) {
                returnVal.children = labelValueFormat(children, label, value);
            }
        }
        return returnVal;
    });
};

export const generateSource = <Data extends object>(
    subject: Subject<unknown>,
    request: () => Promise<HttpResult<Data[]> | undefined>,
    labelKey: keyof Data,
    valueKey: keyof Data
) => {
    return subject.pipe(
        debounceTime(500),
        switchMap(() =>
            from(request()).pipe(
                map((res) => {
                    if (!res) {
                        return [];
                    }
                    return labelValueFormat(res.data, labelKey, valueKey);
                })
            )
        ),
        shareReplay(1)
    );
};

export const excuteSubject = <T>(
    update: () => void,
    source: Observable<T>,
    refData: Ref<T>
) => {
    const subscription = source.subscribe((res) => {
        refData.value = res;
    });
    update();

    return {
        update,
        source,
        refData,
        subscription
    };
};
